<template>
  <view class="update-container">
    <!-- 遮罩层 -->
    <view class="mask" v-if="showMask"></view>

    <!-- 更新弹窗 -->
    <view
      class="update-dialog"
      :class="{ show: showDialog, mandatory: isMandatory }"
    >
      <!-- 顶部装饰 -->
      <view class="dialog-header">
        <image
          class="header-bg"
          src="/static/images/update-header-bg.png"
          mode="aspectFill"
          v-if="!isMandatory"
        ></image>
        <view class="header-content">
          <text class="header-title">{{ title }}</text>
          <text class="header-subtitle">发现新版本</text>
          <view class="version-badge" v-if="version">
            <text class="badge-text">v{{ version }}</text>
          </view>
        </view>
      </view>

      <!-- 主体内容 -->
      <view class="dialog-body">
        <!-- 版本信息 -->
        <view class="version-info">
          <text class="version-label">版本号：</text>
          <text class="version-text">{{ version }}</text>
        </view>

        <!-- 更新内容 -->
        <view class="update-content">
          <text class="content-title">更新内容：</text>
          <scroll-view class="content-scroll" scroll-y>
            <text class="content-text">{{ contents }}</text>
          </scroll-view>
        </view>

        <!-- 文件大小 -->
        <view class="file-size" v-if="pkgSize">
          <text class="size-label">文件大小：</text>
          <text class="size-value">{{ formatSize(pkgSize) }}</text>
        </view>

        <!-- 下载进度 -->
        <view class="download-progress" v-if="downloading">
          <view class="progress-bar">
            <view
              class="progress-fill"
              :style="{ width: progress + '%' }"
            ></view>
          </view>
          <text class="progress-text">{{ progress }}%</text>
        </view>
      </view>

      <!-- 底部按钮 -->
      <view class="dialog-footer">
        <!-- 非强制更新时的取消按钮 -->
        <button
          v-if="!isMandatory"
          class="btn btn-cancel"
          :disabled="downloading"
          @tap="handleCancel"
        >
          <text class="btn-text">{{
            downloading ? "下载中..." : "稍后更新"
          }}</text>
        </button>

        <!-- 确认按钮 -->
        <button
          class="btn btn-confirm"
          :disabled="downloading"
          :loading="installing"
          @tap="handleConfirm"
        >
          <text class="btn-text" v-if="installing">安装中...</text>
          <text class="btn-text" v-else-if="downloading">下载中...</text>
          <text class="btn-text" v-else>{{
            isMandatory ? "立即更新" : "立即更新"
          }}</text>
        </button>
      </view>

      <!-- 关闭按钮（非强制更新时显示） -->
      <view
        v-if="!isMandatory"
        class="close-btn"
        :class="{ disabled: downloading }"
        @tap="handleCancel"
      >
        <text class="close-icon">×</text>
      </view>
    </view>
  </view>
</template>

<script>
import { AppVersionApi } from "@/api/system/appversion";
import appUpdate from "@/utils/appUpdate";

export default {
  name: "UpdatePopup",

  data() {
    return {
      // 弹窗显示控制
      showMask: false,
      showDialog: false,

      // 更新信息
      title: "",
      contents: "",
      version: "",
      pkgUrl: "",
      pkgSize: 0,
      isMandatory: false,
      type: "",

      // 状态控制
      downloading: false,
      installing: false,
      progress: 0,
      tempFilePath: "", // 存储下载的文件路径
      downloadTask: null, // 不再使用，保留为了兼容性

      // 存储键
      localStorageKey: "",
    };
  },

  onLoad(options) {
    this.localStorageKey = options.local_storage_key || "__app_update_info__";
    this.initData();
  },

  onBackPress() {
    // 强制更新时不允许返回
    if (this.isMandatory) {
      return true;
    }
    return false;
  },

  methods: {
    /**
     * 初始化数据
     * 从API获取最新版本信息
     */
    async initData() {
      try {
        // 优先从API获取最新版本信息
        const { data } = await AppVersionApi.getAppVersionPage({
          pageNo: 1,
          pageSize: 1,
        });

        if (!data || !data.list || data.list.length === 0) {
          this.showError("未获取到版本信息");
          return;
        }

        const latestVersion = data.list[0];

        // 验证必要字段
        const requiredFields = ["versionName", "pkgUrl"];
        for (const field of requiredFields) {
          if (!latestVersion[field]) {
            this.showError(`参数 ${field} 必填`);
            return;
          }
        }

        // 赋值 - 遵循开发说明书规范
        this.title = latestVersion.title || "发现新版本";
        this.contents =
          latestVersion.releaseNotes || "优化用户体验，修复已知问题";
        this.version = latestVersion.versionName || "";
        this.pkgUrl = latestVersion.pkgUrl;
        this.pkgSize = latestVersion.pkgSize || 0;
        this.isMandatory = latestVersion.isForce || false;
        this.type = "pkg"; // 默认为全量包类型

        // 显示弹窗
        this.showPopup();
      } catch (error) {
        console.error("从API获取版本信息失败:", error);
      }
    },

    /**
     * 显示弹窗
     */
    showPopup() {
      this.showMask = true;
      this.$nextTick(() => {
        setTimeout(() => {
          this.showDialog = true;
        }, 50);
      });
    },

    /**
     * 处理取消
     */
    handleCancel() {
      if (this.downloading) {
        // 下载中，询问是否取消
        uni.showModal({
          title: "提示",
          content: "确定要取消下载吗？",
          success: (res) => {
            if (res.confirm) {
              this.cancelDownload();
              this.closePopup(false);
            }
          },
        });
      } else {
        this.closePopup(false);
      }
    },

    /**
     * 处理确认
     */
    async handleConfirm() {
      if (this.downloading) {
        return;
      }

      // 开始下载（下载完成后会根据配置自动安装或调用askForInstall直接安装）
      this.startDownload();
    },

    /**
     * 开始下载
     * 统一使用appUpdate.js中的downloadAndInstall方法
     */
    async startDownload() {
      if (!this.pkgUrl) {
        this.showError("下载地址无效");
        return;
      }

      this.downloading = true;
      this.progress = 0;

      try {
        // 构建更新信息对象，适配appUpdate.js的格式
        const updateInfo = {
          url: this.pkgUrl,
          version: this.version,
          versionCode: this.version.replace(/\./g, ''), // 简单版本码转换
          is_mandatory: this.isMandatory,
          type: this.type,
          title: this.title,
          content: this.contents,
          pkg_size: this.pkgSize
        };

        // 使用appUpdate.js的下载方法
        const result = await appUpdate.downloadAndInstall(updateInfo, {
          onProgress: (progress) => {
            this.progress = progress;
          },
          autoInstall: this.isMandatory || this.type === "wgt", // 强制更新或wgt包自动安装
          silentDownload: false
        });

        this.downloading = false;

        // downloadAndInstall方法的行为：
        // - autoInstall为true时：自动安装，不返回结果
        // - autoInstall为false时：调用askForInstall，askForInstall会直接安装
        if (this.isMandatory || this.type === "wgt" || this.autoInstall) {
          // 强制更新、wgt包或设置了autoInstall，都会自动安装
          console.log("自动安装完成");
        } else {
          // 非强制更新且非wgt包且autoInstall为false
          // 此时askForInstall会直接安装，所以我们这里不需要额外处理
          console.log("下载并安装完成");
          // 安装完成后关闭弹窗
          this.closePopup();
        }
      } catch (error) {
        console.error("下载失败:", error);
        this.downloading = false;
        this.showError("下载失败：" + (error.message || "请检查网络后重试"));
        this.resetDownloadState();
      }
    },

    /**
     * 安装包
     * 非自动安装场景下 downloadAndInstall 已直接完成安装，此处无需额外处理
     */
    async installPackage() {
      // 当前逻辑中，非强制更新且非wgt包时，downloadAndInstall 已直接安装完成
      // 因此本函数不再执行实际操作，仅保留接口兼容
      console.log("installPackage 已无需额外处理");
    },

    /**
     * 取消下载
     * 由于使用appUpdate.js的下载方法，这里简化处理
     */
    cancelDownload() {
      // appUpdate.js中的下载任务会在内部处理取消逻辑
      this.resetDownloadState();
    },

    /**
     * 重置下载状态
     */
    resetDownloadState() {
      this.downloading = false;
      this.progress = 0;
      this.tempFilePath = "";
      this.downloadTask = null;
    },

    /**
     * 关闭弹窗
     */
    closePopup(userConfirmed) {
      this.showDialog = false;

      setTimeout(() => {
        this.showMask = false;

        // 清理存储的数据
        try {
          uni.removeStorageSync(this.localStorageKey);
        } catch (error) {
          console.error("清理更新数据失败:", error);
        }

        // 通知调用方用户的选择
        uni.$emit("update-user-choice", userConfirmed);

        // 返回上一页
        uni.navigateBack();
      }, 300);
    },

    /**
     * 格式化文件大小
     * 注意：pkgSize 的单位是 MB（兆字节），不是字节
     */
    formatSize(mb) {
      if (!mb || mb === 0) return "0 MB";

      // 如果小于 1MB，转换为 KB 显示
      if (mb < 1) {
        const kb = mb * 1024;
        return parseFloat(kb.toFixed(0)) + " KB";
      }

      // 如果大于等于 1024MB，转换为 GB 显示
      if (mb >= 1024) {
        const gb = mb / 1024;
        return parseFloat(gb.toFixed(1)) + " GB";
      }

      // 1MB 到 1024MB 之间，保持 MB 单位
      return parseFloat(mb.toFixed(1)) + " MB";
    },

    /**
     * 显示错误信息
     */
    showError(message) {
      uni.showModal({
        title: "错误",
        content: message,
        showCancel: false,
        success: () => {
          this.closePopup(false);
        },
      });
    },

    /**
     * 显示成功信息
     */
    showSuccess(message) {
      uni.showToast({
        title: message,
        icon: "success",
        duration: 1500,
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.update-container {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(10rpx);
  animation: fadeIn 0.3s ease;
}

.update-dialog {
  position: relative;
  width: 640rpx;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border-radius: 32rpx;
  box-shadow: 0 25rpx 80rpx rgba(0, 0, 0, 0.15),
    0 10rpx 30rpx rgba(0, 0, 0, 0.1);
  overflow: hidden;
  opacity: 0;
  transform: scale(0.8);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1rpx solid rgba(255, 255, 255, 0.2);

  &.show {
    transform: scale(1);
    opacity: 1;
  }
}

.dialog-header {
  position: relative;
  height: 240rpx;
  overflow: hidden;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: radial-gradient(
        circle at 20% 80%,
        rgba(255, 255, 255, 0.1) 0%,
        transparent 50%
      ),
      radial-gradient(
        circle at 80% 20%,
        rgba(255, 255, 255, 0.1) 0%,
        transparent 50%
      );
    z-index: 1;
  }

  .header-bg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0.3;
    z-index: 0;
  }

  .header-content {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0 40rpx;
    text-align: center;
  }

  .header-title {
    font-size: 42rpx;
    font-weight: 700;
    color: #ffffff;
    margin-bottom: 12rpx;
    text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
    letter-spacing: 1rpx;
  }

  .header-subtitle {
    font-size: 30rpx;
    color: rgba(255, 255, 255, 0.95);
    font-weight: 400;
    opacity: 0.9;
  }

  .version-badge {
    margin-top: 16rpx;
    padding: 8rpx 20rpx;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 20rpx;
    backdrop-filter: blur(10rpx);
    border: 1rpx solid rgba(255, 255, 255, 0.3);
    animation: fadeInScale 0.6s ease-out 0.3s both;

    .badge-text {
      font-size: 24rpx;
      color: #ffffff;
      font-weight: 600;
      letter-spacing: 0.5rpx;
    }
  }
}

.dialog-body {
  padding: 48rpx 40rpx;
}

.version-info {
  display: flex;
  align-items: center;
  margin-bottom: 32rpx;
  padding: 20rpx 24rpx;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-radius: 16rpx;
  border: 1rpx solid rgba(226, 232, 240, 0.8);

  .version-label {
    font-size: 28rpx;
    color: #64748b;
    margin-right: 16rpx;
    font-weight: 500;
  }

  .version-text {
    font-size: 32rpx;
    font-weight: 700;
    color: #1e293b;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }
}

.update-content {
  margin-bottom: 32rpx;

  .content-title {
    display: block;
    font-size: 30rpx;
    color: #374151;
    margin-bottom: 16rpx;
    font-weight: 600;
    letter-spacing: 0.5rpx;
  }

  .content-scroll {
    max-height: 240rpx;
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    border-radius: 16rpx;
    padding: 24rpx;
    border: 1rpx solid rgba(226, 232, 240, 0.8);
    box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.05);
  }

  .content-text {
    font-size: 28rpx;
    line-height: 1.8;
    color: #475569;
    white-space: pre-wrap;
    font-weight: 400;
  }
}

.file-size {
  display: flex;
  align-items: center;
  margin-bottom: 32rpx;
  padding: 16rpx 0;

  .size-label {
    font-size: 28rpx;
    color: #64748b;
    margin-right: 12rpx;
    font-weight: 500;
  }

  .size-value {
    font-size: 30rpx;
    color: #3b82f6;
    font-weight: 700;
    background: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }
}

.download-progress {
  margin-top: 32rpx;
  padding: 24rpx;
  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
  border-radius: 16rpx;
  border: 1rpx solid rgba(59, 130, 246, 0.2);

  .progress-bar {
    position: relative;
    height: 16rpx;
    background-color: rgba(59, 130, 246, 0.1);
    border-radius: 8rpx;
    overflow: hidden;
    margin-bottom: 20rpx;
    box-shadow: inset 0 2rpx 4rpx rgba(0, 0, 0, 0.1);
  }

  .progress-fill {
    height: 100%;
    background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 50%, #34d399 100%);
    border-radius: 8rpx;
    transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    position: relative;
    overflow: hidden;

    &::after {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.3) 50%,
        transparent 100%
      );
      animation: shimmer 1.5s infinite;
    }
  }

  .progress-text {
    display: block;
    text-align: center;
    font-size: 28rpx;
    color: #3b82f6;
    font-weight: 700;
    letter-spacing: 0.5rpx;
  }
}

@keyframes shimmer {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

.dialog-footer {
  display: flex;
  padding: 0 40rpx 48rpx;
  gap: 24rpx;
}

.btn {
  flex: 1;
  height: 88rpx;
  border-radius: 44rpx;
  font-size: 32rpx;
  font-weight: 600;
  border: none;
  outline: none;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  letter-spacing: 0.5rpx;

  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(
      90deg,
      transparent 0%,
      rgba(255, 255, 255, 0.2) 50%,
      transparent 100%
    );
    transition: left 0.6s ease;
  }

  &:hover::before {
    left: 100%;
  }

  &:active {
    transform: scale(0.96);
  }

  &:disabled {
    opacity: 0.7;
    transform: none;
    cursor: not-allowed;
  }
}

.btn-cancel {
  background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
  color: #64748b;
  border: 1rpx solid rgba(226, 232, 240, 0.8);

  &:active {
    background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);
  }

  &:disabled {
    background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
    color: #94a3b8;
  }
}

.btn-confirm {
  background: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%);
  color: #ffffff;
  box-shadow: 0 8rpx 24rpx rgba(59, 130, 246, 0.3);

  &:active {
    background: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%);
    box-shadow: 0 4rpx 16rpx rgba(59, 130, 246, 0.2);
  }

  &:disabled {
    background: linear-gradient(135deg, #94a3b8 0%, #cbd5e1 100%);
    box-shadow: none;
  }

  .btn-text {
    font-weight: 600;
    letter-spacing: 0.5rpx;
  }
}

.close-btn {
  position: absolute;
  top: 24rpx;
  right: 24rpx;
  width: 64rpx;
  height: 64rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(255, 255, 255, 0.85) 100%
  );
  border-radius: 50%;
  z-index: 10;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);
  border: 1rpx solid rgba(255, 255, 255, 0.3);

  &:active {
    background: linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.85) 0%,
      rgba(255, 255, 255, 0.75) 100%
    );
    transform: scale(0.9);
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.15);
  }

  &.disabled {
    opacity: 0.5;
    pointer-events: none;
  }

  .close-icon {
    font-size: 36rpx;
    color: #64748b;
    line-height: 1;
    font-weight: 300;
    transition: color 0.3s ease;
  }

  &:hover .close-icon {
    color: #374151;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10rpx);
  }
}

@keyframes pulse {
  0%,
  100% {
    box-shadow: 0 8rpx 24rpx rgba(59, 130, 246, 0.3);
  }
  50% {
    box-shadow: 0 12rpx 32rpx rgba(59, 130, 246, 0.5);
  }
}

@keyframes fadeInScale {
  0% {
    opacity: 0;
    transform: scale(0.8);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

// 添加浮动动画到对话框
.update-dialog.show {
  animation: float 3s ease-in-out infinite;
}

// 强制更新时的特殊样式
.update-dialog.mandatory {
  .btn-confirm {
    animation: pulse 2s ease-in-out infinite;
  }
}

// 适配小屏幕
@media screen and (max-height: 600px) {
  .update-dialog {
    width: 90vw;
    max-height: 80vh;
  }

  .dialog-header {
    height: 180rpx;
  }

  .dialog-body {
    padding: 32rpx;
  }

  .content-scroll {
    max-height: 140rpx;
  }
}

// 暗黑模式支持
@media (prefers-color-scheme: dark) {
  .update-dialog {
    background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
    border: 1rpx solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 25rpx 80rpx rgba(0, 0, 0, 0.4),
      0 10rpx 30rpx rgba(0, 0, 0, 0.3);
  }

  .dialog-header {
    background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);
  }

  .version-info {
    background: linear-gradient(135deg, #334155 0%, #475569 100%);
    border: 1rpx solid rgba(255, 255, 255, 0.1);

    .version-label {
      color: #94a3b8;
    }

    .version-text {
      background: linear-gradient(135deg, #818cf8 0%, #c084fc 100%);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      background-clip: text;
    }
  }

  .content-title {
    color: #d1d5db;
  }

  .content-scroll {
    background: linear-gradient(135deg, #334155 0%, #475569 100%);
    border: 1rpx solid rgba(255, 255, 255, 0.1);
  }

  .content-text {
    color: #cbd5e1;
  }

  .size-label {
    color: #94a3b8;
  }

  .size-value {
    background: linear-gradient(135deg, #60a5fa 0%, #38bdf8 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .download-progress {
    background: linear-gradient(135deg, #1e3a8a 0%, #1e40af 100%);
    border: 1rpx solid rgba(59, 130, 246, 0.3);

    .progress-text {
      color: #93c5fd;
    }
  }

  .btn-cancel {
    background: linear-gradient(135deg, #374151 0%, #4b5563 100%);
    color: #d1d5db;
    border: 1rpx solid rgba(255, 255, 255, 0.1);

    &:active {
      background: linear-gradient(135deg, #4b5563 0%, #6b7280 100%);
    }
  }

  .btn-confirm {
    background: linear-gradient(135deg, #2563eb 0%, #3b82f6 100%);
    box-shadow: 0 8rpx 24rpx rgba(37, 99, 235, 0.4);

    &:active {
      background: linear-gradient(135deg, #1d4ed8 0%, #2563eb 100%);
    }
  }

  .close-btn {
    background: linear-gradient(
      135deg,
      rgba(55, 65, 81, 0.95) 0%,
      rgba(75, 85, 99, 0.85) 100%
    );
    border: 1rpx solid rgba(255, 255, 255, 0.2);

    .close-icon {
      color: #d1d5db;
    }

    &:hover .close-icon {
      color: #f3f4f6;
    }
  }
}
</style>
